import { ElNotification } from 'element-plus'
import { queryTypeByDic } from '@/utils/getData'
import { pingProtoData, webSocketLoginData, messageData } from '@/proto/protoData'
import { clickNews } from '@/utils/handleRouter'

// 弹框
import { Message } from '@/proto/ProtoMsg'
// websocket 连接
export let webSocketLink
// 心跳定时器
let webSocketPingTimer = null
// 心跳时间
const webSocketPingTime = 60000
// 重连次数
let webSocketReconnectCount = 0
// 重连定时器
let webSocketReconnectTimer = null
// websocket 是否已经链接了
let webSocketIsOpen = true
// 是否重连
let webSocketIsReconnect = true
// 初始化websocket 连接
export const init = () => {
    if (webSocketLink != null) {
        // 初始化websocket链接
        resetWebSocketLink()
        return
    }
    webSocketLink = new WebSocket(process.env.VUE_APP_WEBSOCKET_WS)
    // 设置webSocket通信二进制
    webSocketLink.binaryType = 'arraybuffer'
    webSocketLink.onopen = function () {
        // 登录websocket
        webSocketIsOpen = false
        webSocketLogin()
    }
    // 接受websocket 消息
    webSocketLink.onmessage = function (event) {
        // 处理二进制数据
        handleBinary(event)

    }
    // 关闭websocket
    webSocketLink.onclose = function () {
        websocketClose()
        // webSocketReconnect()
    }
    // websocket异常
    webSocketLink.onerror = function () {
        webSocketReconnect()
    }
}
// 重置websocket链接
const resetWebSocketLink = () => {
    webSocketLink = null
    webSocketPingTimer = null
    webSocketReconnectTimer = null
}
// 关闭socket连接
const websocketClose = () => {
    webSocketIsOpen = true
    webSocketLink = null
    if (webSocketIsReconnect && webSocketReconnectCount < 5) {
        webSocketReconnect()
    }
}
// 接受到websocket消息
const handleBinary = (event) => {
    if (!(event.data instanceof ArrayBuffer)) {
        return
    }
    // 解析arraybuffer数据
    const reader = new FileReader()
    let buffer = new Blob([event.data])
    reader.readAsArrayBuffer(buffer)
    reader.onloadend = function () {
        const buf = new Uint8Array(this.result)
        // 处理返回数据
        handleRuturnMessage(Message.decode(buf))
    }
}

// 处理解码后的数据
const handleRuturnMessage = async (data) => {
    console.log(data)
    if (data) {
        // 登录
        if (data.type === 1) {
            // 登录成功时,则直接添加心跳
            if (data.loginResponse?.code === 0 && data.loginResponse?.info === 'Success') {
                webSocketPing()
            } else {
                // 登录失败则直接关闭当前连接
                websocketClose()
                //Notify('网络异常，请重新登录')
            }
        } else {
            // 其他类型处理
            console.log(data)
            // 获取通知类型
            let noticeType = await queryTypeByDic('noticeCode')
            let msg = JSON.parse(data.notification.json)

            noticeType.forEach(item => {
                if (item.value == msg.type) {
                    msg.typeName = item.name
                }
            })
            ElNotification({
                title: msg.title,
                message: `【${msg.typeName}】`,
                position: 'bottom-right',
                'custom-class': 'msgBox',
                duration: 0,
                onClick: () => {
                    console.log(msg)
                    clickNews(msg)
                }
            })
        }
    } else {
        // 服务端数据不匹配，则直接关闭websocket连接
        websocketClose()
        //Notify('服务端数据不匹配，请重新登录')
    }
}
// websocket 重连
const webSocketReconnect = () => {
    if (webSocketLink != null) {
        return false
    }
    webSocketReconnectCount += 1
    if (!webSocketIsOpen) {
        return false
    }
    clearTimeout(webSocketReconnectTimer)
    if (webSocketReconnectCount >= 20) {
        return false
    }
    // 初始化websocket连接
    init()
    // 每过 5 秒尝试一次，检查是否连接成功，直到超过最大重连次数
    clearTimeout(webSocketReconnectTimer)
    webSocketReconnectTimer = setTimeout(() => {
        webSocketReconnect()
    }, 5000)
}
// 发送心跳连接
const webSocketPing = () => {
    if (webSocketIsOpen) {
        return false
    }
    if (webSocketLink.readyState !== 1) {
        return
    }
    clearTimeout(webSocketPingTimer)
    webSocketPingTimer = setTimeout(() => {
        // 发送心跳信息
        webSocketSend()
        webSocketPing()
    }, webSocketPingTime)
}

// 发送心跳信息
const webSocketSend = () => {
    webSocketSendMessage(pingProtoData())
}

//websocket 发送登录信息
const webSocketLogin = () => {
    if (webSocketLink.readyState == 1) {
        webSocketSendMessage(webSocketLoginData())
    }
}

//websocket 发送信息
export const sendMessage = (data) => {
    webSocketSendMessage(messageData(data))
}

const webSocketSendMessage = (data) => {
    webSocketLink.send(data)
}


